#include "abstractmodelitem.h"


#include <QTimer>
#include <QMetaType>
#include <QDebug>


AbstractModelItem::AbstractModelItem(QObject *parent) :
    QObject(parent)
{
    QTimer::singleShot(0, this, SLOT(onInitialize()));
    QTimer::singleShot(0, this, SLOT(onReparent()));
}


AbstractModelItem::AbstractModelItem(const AbstractModelItem &other) :
    QObject(other.parent())
{
    QTimer::singleShot(0, this, SLOT(onReparent()));
}


AbstractModelItem *AbstractModelItem::create(int type, QObject *parent)
{
    if (!QMetaType::isRegistered(type)) return 0;

    AbstractModelItem* item = reinterpret_cast<AbstractModelItem*>(QMetaType::construct(type));
    if (!item) return 0;

    item->setParent(parent);
    item->onInitialize();

    return item;
}


AbstractModelItem *AbstractModelItem::create(const QString &typeName, QObject *parent)
{
    return create(QMetaType::type(typeName.toAscii()), parent);
}

const AbstractModelItem *AbstractModelItem::root() const
{
    AbstractModelItem* item = qobject_cast<AbstractModelItem*>(parent());
    if (!item) return qobject_cast<const AbstractModelItem*>(this);

    return item->root();
}


QList<AbstractModelItem *> AbstractModelItem::childItems() const
{
    QList<AbstractModelItem *> ret;

    foreach (QObject* obj, children())
    {
        AbstractModelItem* base = qobject_cast<AbstractModelItem*>(obj);
        if (!base) continue;

        ret << base;
    }

    return ret;
}

int AbstractModelItem::type() const
{
    int ret = QMetaType::type(metaObject()->className());

    return ret;
}


void AbstractModelItem::setParent(QObject *object)
{
    AbstractModelItem* item = qobject_cast<AbstractModelItem*>(parent());

    if (item)
    {
        disconnect(item, SIGNAL(sigChanged()));
    }

    QObject::setParent(object);

    onReparent();
}


void AbstractModelItem::onReparent()
{
    AbstractModelItem* item = qobject_cast<AbstractModelItem*>(parent());

    if (!item) return;

    connect(this, SIGNAL(sigChanged()), item, SIGNAL(sigChanged()));
}


void AbstractModelItem::onInitialize()
{
}






